﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.IO.Ports;
using n_MySerialPort;
using System.Text.RegularExpressions;
using System.Globalization;
using n_CWavePanel;
using c_MIDI;

namespace n_CMusicForm
{
	/// <summary>
	/// Description of MainForm.
	/// </summary>
	public partial class CMusicForm : Form
	{
		//串口接收事件(仿真时由硬件发送)
		public delegate bool D_GetSimStatus();
		public static D_GetSimStatus deleGetSimStatus;
		
		//串口下发事件(仿真时由硬件接收)
		public delegate void D_SendData( byte b );
		public static D_SendData deleSendData;
		
		
		public bool SingleMode = true;
		
		//串行端口
		System.IO.Ports.SerialPort port;
		byte[] buffer;
		
		bool isSim;
		public bool isOpen;
		
		CWavePanel CWaveBox;
		
		int CIndex;
		byte[] ProBuffer;
		
		
		//主窗口
		public CMusicForm()
		{
			InitializeComponent();
			
			this.comboBox波特率.Text = "9600";
			//RefreshUARTList();
			buffer = new byte[ 500 ];
			
			ProBuffer = new byte[20];
			CIndex = 0;
			
			isSim = false;
			isOpen = false;
			
			SingleMode = false;
			
			CWaveBox = new CWavePanel();
			this.panel2.Controls.Add( CWaveBox );
			
			this.MouseWheel += new MouseEventHandler( CWaveBox.MWheel );
			
			Music.Open();
		}
		
		//运行
		public void Run()
		{
			this.Visible = true;
		}
		
		//打开端口
		void Open( string COMNumber, int Baud )
		{
			if( COMNumber == "COM0" ) {
				isSim = true;
				return;
			}
			
			isSim = false;
			
			port = new System.IO.Ports.SerialPort( COMNumber );
			port.BaudRate = Baud;
			port.DataBits = 8;
			port.Parity = System.IO.Ports.Parity.None;
			port.StopBits = System.IO.Ports.StopBits.One;
			port.ReadTimeout = 1;
			
			if( checkBoxDTR_RTS.Checked ) {
				port.DtrEnable = true;
				port.RtsEnable = true;
			}
			else {
				port.DtrEnable = false;
				port.RtsEnable = false;
			}
			
			port.DataReceived += new SerialDataReceivedEventHandler( DataReceived );
			try {
				port.Open();
			}
			catch {
				MessageBox.Show( "ERROR" );
				port = null;
			}
			
//			port = new Port();
//			port.PortNum = COMNumber;
//			port.BaudRate = Baud;
//			port.ByteSize = 8;
//			port.Parity = (byte)System.IO.Ports.Parity.None;
//			port.StopBits = (byte)System.IO.Ports.StopBits.One;
//			port.ReadTimeout = 1;
//			try {
//				if( port.Opened ) {
//					port.Close();
//					port.Open(); //打开串口
//				}
//				else {
//					port.Open();//打开串口
//				}
//			}
//			catch {
//				MessageBox.Show( "串口初始化失败" );
//			}
			
			//timer.Enabled = true;
		}
		
		//数据接收事件
		void DataReceived(object sender, EventArgs e)
		{
			try {
				int n = port.Read( buffer, 0, 100 );
				if( n == 0 ) {
					return;
				}
				for( int i = 0; i < n; ++i ) {
					byte b = buffer[ i ];
					AddByte( b );
				}
			}
			catch {
				
			}
		}
		
		//添加一个字节到显示窗口
		void AddByte( byte b )
		{
			ProBuffer[CIndex] = b;
			++CIndex;
			
			if( CIndex == 1 ) {
				if( b == 0xAA ) {
					return;
				}
				this.Text += "E";
				CIndex = 0;
				return;
			}
			if( CIndex < 4 ) {
				return;
			}
			CIndex = 0;
			
			int Ch = ProBuffer[1];
			
			int Tone = ProBuffer[ 2 ];
			int vol = ProBuffer[ 3 ];
			
			Music.PlaySound( Ch, Tone, vol );
			
			CWaveBox.SetChannelData( Ch, Tone, vol );
			
			CWaveBox.Invalidate();
		}
		
		//窗体关闭事件
		void UARTFormFormClosing(object sender, FormClosingEventArgs e)
		{
			if( !SingleMode ) {
				this.Visible = false;
				e.Cancel = true;
				return;
			}
			try {
				if( port != null && port.IsOpen ) {
					port.Close();
				}
			}
			catch {
				MessageBox.Show( "CLOSE ERROR" );
				port = null;
			}
			Music.Close();
			
			//this.Visible = false;
			//e.Cancel = true;
			//timer.Enabled = false;
		}
		
		public void Button打开串口Click(object sender, EventArgs e)
		{
			if( button打开串口.Text == "关闭串口" ) {
				if( !isSim ) {
					try{
						port.Close();
						port = null;
					}
					catch {
						MessageBox.Show( "串口关闭失败!" );
					}
				}
				isOpen = false;
				button打开串口.Text = "打开串口";
				button打开串口.BackColor = Color.DarkGray;
				return;
			}
			else {
				try{
					string Name = this.comboBox串口号.Text;
					string Baud = this.comboBox波特率.Text;
					int BaudN = int.Parse( Baud );
					Open( MySerialPort.GetComName( Name ), BaudN );
				}
				catch {
					MessageBox.Show( "串口打开失败!" );
					return;
				}
				if( !isSim && port == null ) {
					return;
				}
				isOpen = true;
				button打开串口.Text = "关闭串口";
				button打开串口.BackColor = Color.Green;
			}
		}
		
		void ComboBox串口号Click(object sender, EventArgs e)
		{
			this.comboBox串口号.Items.Clear();
			
			if( deleGetSimStatus != null && deleGetSimStatus() ) {
				this.comboBox串口号.Items.Add( "COM0 linkboy仿真端口" );
			}
			
			//通过WMI获取COM端口
			string[] ss = MySerialPort.GetFullNameList();
			if( ss != null ) {
				this.comboBox串口号.Items.AddRange( ss );
			}
		}
		
		void ComboBoxTimberSelectedIndexChanged(object sender, EventArgs e)
		{
			string t = comboBoxTimber.Text;
			int i = t.IndexOf( ' ' );
			if( i == -1 ) {
				MessageBox.Show( "请选择音色" );
				return;
			}
			t = t.Remove( i );
			int Index = int.Parse( t );
			Music.SetTimbre( 0, Index );
		}
		
		void Timer1Tick(object sender, EventArgs e)
		{
			CWaveBox.AutoChange();
			CWaveBox.Invalidate();
		}
	}
}

